home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
tcplusx.zip
/
KEYBOARD.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-28
|
7KB
|
306 lines
//
// keyboard.cpp - implementation for class Keyboard
// Author - Robin W. McKean
// Last Update - February 21,1991
// Copyright (C) 1991 All rights reserved
//
// This file remains the property of the author, Robin W. McKean. You are
// free to use and change it as you see fit. This module, nor its object
// code, may not however be included in any packaged software without the
// written consent of the author.
//
// Contents ----------------------------------------------------------------
//
// Keyboard::Keyboard
// Keyboard::isA
// Keyboard::nameOf
// Keyboard::processA
// Keyboard::pollDevice
//
// Description
//
// Defines the class Keyboard. The purpose of this class is to input
// information from the keyboard, tranlate that into an event and pass
// it back to the user for processing.
//
// End ---------------------------------------------------------------------
// Interface dependencies --------------------------------------------------
#ifndef _IOSTREAM_H
#include <iostream.h>
#endif
#ifndef _USETYPES_H
#include <usetypes.h>
#endif
#ifndef _GEN_H
#include <gen.h>
#endif
#ifndef _EVENT_H
#include <event.h>
#endif
#ifndef _KEYBOARD_H
#include <keyboard.h>
#endif
// End Interface dependencies ----------------------------------------------
// Implementation dependencies ---------------------------------------------
#ifndef _DOS_H
#define _DOS_H
#include <dos.h>
#endif
#ifndef _CONIO_H
#define _CONIO_H
#include <conio.h>
#endif
// End Implementation dependencies -----------------------------------------
unsigned readKey( unsigned char enhancedBIOS );
// Member Function //
Keyboard::Keyboard( int initStatus ) : Device( initStatus )
// Summary ------------------------------------------------------------------
//
// Sets the initial status of the keyboard, and resets the control
// break function
//
// End ---------------------------------------------------------------------
{
type = D_KEYBOARD; // Set the keyboard type
enhancedBIOS = 0; // Set default state of enhanced BIOS
REGS regs; // Check for enhanced BIOS
regs.h.ah = 5;
regs.x.cx = 0xffff;
int86( 0x16, ®s, ®s );
// AL = 0 if enhanced BIOS are present
if( regs.h.al == 0 )
enhancedBIOS = 0x10;
else
enhancedBIOS = 0;
// Now, lets get the control break status, and reset it with ours
regs.h.ah = 0x33;
regs.h.al = 0;
int86( 0x21, ®s, ®s );
breakStatus = regs.h.dl; // Save the current break status
// Now disable control break
regs.h.ah = 0x33;
regs.h.al = 1;
regs.h.dl = 0;
int86( 0x21, ®s, ®s );
altKeyStatus = 0;
}
// End Keyboard::Keyboard //
// Member Function //
#pragma argsused
Keyboard::Keyboard( Keyboard& theDevice )
// Description -------------------------------------------------------------
//
// Copies one Keyboard into another
//
// Parameters
//
// Device&
//
// The Keyboard to be copied
//
// End ---------------------------------------------------------------------
{
}
// End Keyboard::Keyboard //
// Member Function
Keyboard::~Keyboard( )
{
// Reset the control break status
REGS regs;
regs.h.ah = 0x33;
regs.h.al = 1;
regs.h.dl = breakStatus;
int86( 0x21, ®s, ®s );
}
// Keyboard::~Keyboard //
// Member Function //
classType Keyboard::isA( ) const
// Description -------------------------------------------------------------
//
// Returns a value representation of a class
//
// End ---------------------------------------------------------------------
{
return keyboardClass;
}
// End Keyboard::isA( ) //
// Member Function //
char *Keyboard::nameOf( ) const
// Description -------------------------------------------------------------
//
// Returns a character representation of a class
//
// End ---------------------------------------------------------------------
{
return "Keyboard";
}
// End Keyboard::nameOf //
// Member Function
void Keyboard::pollDevice( )
// Description -------------------------------------------------------------
//
// Reads the keyboard if a keystroke is waiting. It then builds an
// event from the keystroke and the key shift state. If the keyboard
// status is D_ON, it puts the key into the EventManagers queue.
//
// End ---------------------------------------------------------------------
{
REGS regs;
unsigned int key = 0;
unsigned int shiftKey;
// Read the current shift state first
regs.h.ah = 2;
int86( 0x16, ®s, ®s );
// Shift key status stored in AL
shiftKey = ( unsigned )regs.h.al;
int newAltKey = ( int ) shiftKey & K_ALT;
// Check to see if there is a keystroke waiting
if( !kbhit( ) )
{
// No keystroke, now check to see if Alt key status has changed
if( altKeyStatus && !newAltKey )
{
altKeyStatus = 0; // Alt key was pressed, now released
key = ALT_KEY_PRESSED; // Translate into F10
}
else
{
altKeyStatus = newAltKey; // Change the alt key status to
newAltKey = 0; // current status
}
}
// We know there is a key stroke waiting, so fetch it
else
{
key = readKey( enhancedBIOS );
altKeyStatus = 0;
}
// If there was something in key, than build an event,
// but not if the keyboard is disabled
if( key && status == D_ON )
{
Event event;
event.type = E_KEY;
event.typeCode = key;
event.shiftState = shiftKey;
if( theEventManager ) theEventManager->putEvent( event, FALSE );
}
}
int Keyboard::processA( Event& theEvent )
{
if( theEvent.type == S_DEVICE && status != D_INACTIVE )
{
switch( theEvent.type )
{
case D_OFF:
case D_ON:
status = theEvent.type;
break;
}
}
return( 0 );
}
// This is a function that I use to read the keyboard. It comes from
// the MicroSoft QuickC compiler, with some few adjustments I have made
#pragma argsused
unsigned readKey( unsigned char enhancedBIOS )
{
unsigned iKey, iShiftstatus;
// Get key code.
_AH = enhancedBIOS; // Non-portable code!
geninterrupt( 0x16 );
iKey = _AX; // Non-portable code!
iShiftstatus = ( unsigned )*( ( unsigned char far * ) 0x417L ) & 0x0f;
// If low byte is not zero, it's an ASCII key. Check scan code to see
// if it's on the numeric keypad. If not, clear high byte and return.
if( iKey & 0x00ff )
if( (iKey >> 8) < 69 ) {
iKey = ( iKey & 0x00ff );
iShiftstatus &= 0x000f;
switch( iShiftstatus ) {
case 4:
return( 0x0500 | iKey ); // Control ( 5 )
case 8:
return( 0x0600 | iKey ); // Alt ( 6 )
default:
return( 0x0000 | iKey );
}
}
// For function keys and numeric keypad, put scan code in low byte
// and shift state codes in high byte.
iKey >>= 8;
iShiftstatus &= 0x000f;
switch( iShiftstatus )
{
case 0:
return( 0x0100 | iKey ); // None (1)
case 1:
case 2:
case 3:
return( 0x0200 | iKey ); // Shift (2)
case 4:
return( 0x0300 | iKey ); // Control (3)
case 8:
return( 0x0400 | iKey ); // Alt (4)
}
return( 0 );
}